#include <iostream>
#include <nlohmann/json.hpp>

static void json1()
{
    nlohmann::json jsonObject = {
        {"name", "John"},
        {"age", 30},
        {"address", {
            {"street", "123 Main St"},
            {"city", "New York"},
            {"zipcode", "10001"}
        }},
        {"phone_numbers", {"123-456-7890", "987-654-3210"}}
    };

    // 访问嵌套数据
    std::string city = jsonObject["address"]["city"];
    std::string first_phone = jsonObject["phone_numbers"][0];

    std::cout << "City: " << city << std::endl;
    std::cout << "First Phone Number: " << first_phone << std::endl;

    // 输出整个 JSON 对象
    std::cout << jsonObject.dump(4) << std::endl;
}


static void json2()
{
    nlohmann::json jsonObject = {
        {"name", "John"},
        {"age", 30},
        {"skills", {"C++", "Python", "Java"}}
    };

    // 迭代 JSON 对象
    for (auto& [key, value] : jsonObject.items()) {
        std::cout << key << ": " << value << std::endl;
    }

    // 迭代 JSON 数组
    for (const auto& skill : jsonObject["skills"]) {
        std::cout << "Skill: " << skill << std::endl;
    }
}


struct Person {
    std::string name;
    int age;
};


// 将 Person 转换为 JSON
void to_json(nlohmann::json& j, const Person& p) {
    j = nlohmann::json{{"name", p.name}, {"age", p.age}};
}

// 从 JSON 转换为 Person
void from_json(const nlohmann::json& j, Person& p) {
    j.at("name").get_to(p.name);
    j.at("age").get_to(p.age);
}

void json3()
{
    Person person = {"John", 30};

    // 序列化
    nlohmann::json jsonObject = person;
    std::cout << jsonObject.dump(4) << std::endl;

    // 反序列化
    std::string jsonString = R"({"name": "Jane", "age": 25})";
    nlohmann::json parsedJson = nlohmann::json::parse(jsonString);
    Person newPerson = parsedJson.get<Person>();

    std::cout << "Name: " << newPerson.name << std::endl;
    std::cout << "Age: " << newPerson.age << std::endl;
}

int main() {
    json3();
    json1();
    json2();
    
    return 0;
}
